#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include "mdtx-online/indicator/indicator_type_s2.h"
using namespace mdtx::online;

#include "indi_common.h"

using ulcer_ = indi1<indicator::ulcer>;

//' Ulcer
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector ulcer(NumericVector x, int period)
{
    auto c = ulcer_::create_t(period);
    return ulcer_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP ulcer_new(int period)
{
    return ulcer_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector ulcer_run(SEXP ptr, NumericVector x)
{
    return ulcer_::run(ptr, x);
}

using bband_ = indi2<indicator::bband>;

//' Bollinger Bands
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param z zscore threshold
//' @return List of upper and lower band
//' @export
// [[Rcpp::export(rng = false)]]
List bband(NumericVector x, int period, double z)
{
    auto c = bband_::create_t(period, z);
    auto ans = bband_::run_t(c, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP bband_new(int period, double z)
{
    return bband_::create(period, z);
}

// [[Rcpp::export(rng = false)]]
List bband_run(SEXP ptr, NumericVector x)
{
    auto ans = bband_::run(ptr, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}

using zbband_ = indi2<indicator::zbband>;

//' Bollinger Bands, smoothed zscore
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param z zscore threshold
//' @param r attenuate factor
//' @return List of upper and lower band
//' @export
// [[Rcpp::export(rng = false)]]
List zbband(NumericVector x, int period, double z, double r)
{
    auto c = zbband_::create_t(period, z, r);
    auto ans = zbband_::run_t(c, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP zbband_new(int period, double z, double r)
{
    return zbband_::create(period, z, r);
}

// [[Rcpp::export(rng = false)]]
List zbband_run(SEXP ptr, NumericVector x)
{
    auto ans = zbband_::run(ptr, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}

using ebband_ = indi2<indicator::ebband>;

//' Bollinger Bands, exponential
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param z zscore threshold
//' @return List of upper and lower band
//' @export
// [[Rcpp::export(rng = false)]]
List ebband(NumericVector x, int period, double z)
{
    auto c = ebband_::create_t(period, z);
    auto ans = ebband_::run_t(c, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP ebband_new(int period, double z)
{
    return ebband_::create(period, z);
}

// [[Rcpp::export(rng = false)]]
List ebband_run(SEXP ptr, NumericVector x)
{
    auto ans = ebband_::run(ptr, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}

using ezband_ = indi2<indicator::ezband>;

//' Bollinger Bands, smoothed zscore exponential weighted
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param z zscore threshold
//' @param r attenuate factor
//' @return List of upper and lower band
//' @export
// [[Rcpp::export(rng = false)]]
List ezband(NumericVector x, int period, double z, double r)
{
    auto c = ezband_::create_t(period, z, r);
    auto ans = ezband_::run_t(c, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP ezband_new(int period, double z, double r)
{
    return ezband_::create(period, z, r);
}

// [[Rcpp::export(rng = false)]]
List ezband_run(SEXP ptr, NumericVector x)
{
    auto ans = ezband_::run(ptr, x);
    ans.names() = CharacterVector::create("upper", "lower");
    return ans;
}
